#include "ImageMappingManager.h"
#include <QDebug>
#include <QFile>
#include <QFileInfo>
#include <QDir>
#include <QRegularExpression>

ImageMappingManager::ImageMappingManager(QObject *parent)
    : QObject(parent)
    , m_fovRows(1)
    , m_fovCols(1)
    , m_fixtureRows(1)
    , m_fixtureCols(1)
    , m_renamingPattern("%1%2%3%4%5") // 默认重命名模式
{
    // 设置临时文件夹
    m_tempFolder = QDir::tempPath() + "/HalconImages";
}

void ImageMappingManager::setParameters(int fovRows, int fovCols, int fixtureRows, int fixtureCols)
{
    if (m_fovRows != fovRows || m_fovCols != fovCols ||
        m_fixtureRows != fixtureRows || m_fixtureCols != fixtureCols) {

        m_fovRows = fovRows;
        m_fovCols = fovCols;
        m_fixtureRows = fixtureRows;
        m_fixtureCols = fixtureCols;

        emit parametersChanged();
    }
}

void ImageMappingManager::getParameters(int &fovRows, int &fovCols, int &fixtureRows, int &fixtureCols) const
{
    fovRows = m_fovRows;
    fovCols = m_fovCols;
    fixtureRows = m_fixtureRows;
    fixtureCols = m_fixtureCols;
}

bool ImageMappingManager::scanImageFolder(const QString& folderPath)
{
    QStringList imageFiles = getImageFilesFromFolder(folderPath);

    if (imageFiles.isEmpty()) {
        emit scanCompleted(false, "未找到图像文件！");
        return false;
    }

    if (!validateParameters()) {
        emit scanCompleted(false, "参数设置错误，请检查行列数设置！");
        return false;
    }

    m_currentFolder = folderPath;
    m_imageInfoMap.clear();

    // 初始化文件信息
    for (const QString& fileName : imageFiles) {
        QString fullPath = folderPath + "/" + fileName;
        m_imageInfoMap[fileName] = ImageFileInfo(fileName, "", fullPath, ImageCoordinate());
    }

    // 计算坐标
    if (calculateCoordinates()) {
        emit scanCompleted(true, QString("成功扫描 %1 个图像文件").arg(imageFiles.size()));
        emit mappingUpdated();
        return true;
    } else {
        emit scanCompleted(false, "坐标计算失败！");
        return false;
    }
}

bool ImageMappingManager::calculateCoordinates()
{
    int totalFOVPerFixture = m_fovRows * m_fovCols;
    int totalFixtures = m_fixtureRows * m_fixtureCols;
    int totalExpectedImages = totalFOVPerFixture * totalFixtures;

    if (m_imageInfoMap.size() != totalExpectedImages) {
        qWarning() << "图像数量与参数不匹配: 实际=" << m_imageInfoMap.size()
                << "预期=" << totalExpectedImages;
        return false;
    }

    int imageIndex = 0;
    QStringList fileNames = m_imageInfoMap.keys();

    // 按照治具行->治具列->FOV行->FOV列的顺序分配坐标
    for (int fr = 0; fr < m_fixtureRows; ++fr) {
        for (int fc = 0; fc < m_fixtureCols; ++fc) {
            for (int fvr = 0; fvr < m_fovRows; ++fvr) {
                for (int fvc = 0; fvc < m_fovCols; ++fvc) {
                    if (imageIndex < fileNames.size()) {
                        QString fileName = fileNames.at(imageIndex);
                        ImageCoordinate coord(fr, fc, fvr, fvc);

                        // 更新文件信息
                        ImageFileInfo info = m_imageInfoMap[fileName];
                        info.coordinate = coord;
                        info.renamedName = generateHalconCompatibleName(fileName, coord);
                        m_imageInfoMap[fileName] = info;
                        imageIndex++;
                    } else {
                        break;
                    }
                }
            }
        }
    }

    return true;
}

bool ImageMappingManager::renameImagesForHalcon(const QString& outputFolder)
{
    QString targetFolder = outputFolder.isEmpty() ? m_tempFolder : outputFolder;

    // 创建目标文件夹
    QDir dir(targetFolder);
    if (!dir.exists()) {
        if (!dir.mkpath(".")) {
            emit imagesRenamed(false, "无法创建目标文件夹: " + targetFolder);
            return false;
        }
    }

    // 清空目标文件夹（如果存在旧文件）
    dir.setNameFilters(QStringList() << "*.*");
    dir.setFilter(QDir::Files);
    for (const QString& file : dir.entryList()) {
        dir.remove(file);
    }

    // 复制并重命名文件
    int successCount = 0;
    for (const ImageFileInfo& info : m_imageInfoMap.values()) {
        QString sourcePath = info.fullPath;
        QString targetPath = targetFolder + "/" + info.renamedName;

        if (QFile::copy(sourcePath, targetPath)) {
            successCount++;
        } else {
            qWarning() << "复制文件失败:" << sourcePath << "->" << targetPath;
        }
    }

    bool success = (successCount == m_imageInfoMap.size());
    QString message = success ?
                          QString("成功重命名并复制 %1 个文件到: %2").arg(successCount).arg(targetFolder) :
                          QString("部分文件重命名失败: 成功 %1/%2").arg(successCount).arg(m_imageInfoMap.size());

    emit imagesRenamed(success, message);
    return success;
}

QString ImageMappingManager::generateHalconCompatibleName(const QString& originalName, const ImageCoordinate& coord) const
{
    QFileInfo fileInfo(originalName);
    QString extension = fileInfo.suffix();

    // 使用坐标生成Halcon兼容的文件名
    QString newName = m_renamingPattern
                          .arg(coord.fixtureRow, 2, 10, QChar('0'))
                          .arg(coord.fixtureCol, 2, 10, QChar('0'))
                          .arg(coord.fovRow, 2, 10, QChar('0'))
                          .arg(coord.fovCol, 2, 10, QChar('0'))
                          .arg(extension.isEmpty() ? "" : "." + extension);

    return sanitizeFileName(newName);
}

QString ImageMappingManager::sanitizeFileName(const QString& fileName) const
{
    // 移除或替换Halcon不兼容的字符
    QString sanitized = fileName;
    sanitized.replace(QRegularExpression("[^a-zA-Z0-9._-]"), "_");
    sanitized.replace("__", "_"); // 避免多个连续下划线

    return sanitized;
}

bool ImageMappingManager::saveMappingToConfig(const QString& configPath)
{
    QJsonObject root;

    // 保存参数
    root["fovRows"] = m_fovRows;
    root["fovCols"] = m_fovCols;
    root["fixtureRows"] = m_fixtureRows;
    root["fixtureCols"] = m_fixtureCols;
    root["currentFolder"] = m_currentFolder;
    root["renamingPattern"] = m_renamingPattern;
    root["tempFolder"] = m_tempFolder;

    // 保存文件信息映射
    QJsonArray mappingArray;
    for (const ImageFileInfo& info : m_imageInfoMap.values()) {
        mappingArray.append(info.toJson());
    }
    root["imageInfo"] = mappingArray;

    // 写入文件
    QFile file(configPath);
    if (!file.open(QIODevice::WriteOnly)) {
        return false;
    }

    file.write(QJsonDocument(root).toJson());
    file.close();

    return true;
}

bool ImageMappingManager::loadMappingFromConfig(const QString& configPath)
{
    QFile file(configPath);
    if (!file.open(QIODevice::ReadOnly)) {
        return false;
    }

    QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
    file.close();

    if (doc.isNull()) {
        return false;
    }

    QJsonObject root = doc.object();

    // 加载参数
    m_fovRows = root["fovRows"].toInt();
    m_fovCols = root["fovCols"].toInt();
    m_fixtureRows = root["fixtureRows"].toInt();
    m_fixtureCols = root["fixtureCols"].toInt();
    m_currentFolder = root["currentFolder"].toString();
    m_renamingPattern = root["renamingPattern"].toString(m_renamingPattern);
    m_tempFolder = root["tempFolder"].toString(m_tempFolder);

    // 加载文件信息
    m_imageInfoMap.clear();
    QJsonArray mappingArray = root["imageInfo"].toArray();
    for (const QJsonValue& value : mappingArray) {
        ImageFileInfo info = ImageFileInfo::fromJson(value.toObject());
        m_imageInfoMap[info.originalName] = info;
    }

    emit parametersChanged();
    emit mappingUpdated();

    return true;
}

int ImageMappingManager::getCalculatedTotalImages() const
{
    return m_fovRows * m_fovCols * m_fixtureRows * m_fixtureCols;
}

QMap<QString, ImageCoordinate> ImageMappingManager::getImageCoordinateMap() const
{
    QMap<QString, ImageCoordinate> coordMap;
    for (auto it = m_imageInfoMap.constBegin(); it != m_imageInfoMap.constEnd(); ++it) {
        coordMap[it.key()] = it.value().coordinate;
    }
    return coordMap;
}

QStringList ImageMappingManager::getOriginalImageFiles() const
{
    return m_imageInfoMap.keys();
}

QStringList ImageMappingManager::getRenamedImageFiles() const
{
    QStringList renamedFiles;
    for (const ImageFileInfo& info : m_imageInfoMap.values()) {
        renamedFiles.append(info.renamedName);
    }
    return renamedFiles;
}

ImageCoordinate ImageMappingManager::getImageCoordinate(const QString& fileName) const
{
    return m_imageInfoMap.value(fileName, ImageFileInfo()).coordinate;
}

ImageFileInfo ImageMappingManager::getImageInfo(const QString& fileName) const
{
    return m_imageInfoMap.value(fileName, ImageFileInfo());
}

QString ImageMappingManager::getRenamedPath(const QString& originalFileName) const
{
    ImageFileInfo info = m_imageInfoMap.value(originalFileName);
    if (!info.renamedName.isEmpty()) {
        return m_tempFolder + "/" + info.renamedName;
    }
    return "";
}

bool ImageMappingManager::validateParameters() const
{
    return (m_fovRows > 0 && m_fovCols > 0 && m_fixtureRows > 0 && m_fixtureCols > 0);
}

bool ImageMappingManager::isMappingValid() const
{
    if (m_imageInfoMap.isEmpty()) return false;

    int expectedTotal = getCalculatedTotalImages();
    return (m_imageInfoMap.size() == expectedTotal);
}

QString ImageMappingManager::getStatusMessage() const
{
    if (m_imageInfoMap.isEmpty()) {
        return "未加载图像文件";
    }

    int expected = getCalculatedTotalImages();
    int actual = m_imageInfoMap.size();

    if (expected == actual) {
        return QString("已加载 %1 个图像，映射正确").arg(actual);
    } else {
        return QString("警告: 实际图像数(%1)与预期(%2)不匹配").arg(actual).arg(expected);
    }
}

void ImageMappingManager::cleanupTempFolder()
{
    QDir dir(m_tempFolder);
    if (dir.exists()) {
        dir.removeRecursively();
    }
}

QStringList ImageMappingManager::getImageFilesFromFolder(const QString& folderPath)
{
    QDir dir(folderPath);
    QStringList filters;
    filters << "*.jpg" << "*.jpeg" << "*.png" << "*.bmp" << "*.tiff" << "*.tif";

    QStringList imageFiles = dir.entryList(filters, QDir::Files, QDir::Name);
    return imageFiles;
}
